//////////////////////////////////////////////////////////////////////////
#pragma once


//////////////////////////////////////////////////////////////////////////
#include <Core/Core.hpp>
#include <Config/Config.hpp>
#include <Config/SerializersMath.hpp>
#include <TweakUtils/TweakPanel.hpp>
#include <FileSystem/RocketFileInterface.hpp>
#include <SFML/Window.hpp>
#include <SFML/Graphics.hpp>
#include "RocketSystemInterface.hpp"
#include "RocketRenderInterface.hpp"
#include <Script/Script.hpp>
#include "Clock.hpp"
#include <Application/GameWindow.hpp>


namespace Application
{
	//////////////////////////////////////////////////////////////////////////
	// Forward references.
	class WindowedApp;
	class Clock;

	//////////////////////////////////////////////////////////////////////////
	// Integration point for SFML, primary Rocket UI interactions
	// and the tweak UI.
	// TODO: Should move to UI library.
	class WindowManager
	{
	public:
		//////////////////////////////////////////////////////////////////////////
		typedef std::vector< std::string >			StringVector_t;

		//////////////////////////////////////////////////////////////////////////
		WindowManager( Application::WindowedApp* app, Core::Script& script );
		~WindowManager();

		//////////////////////////////////////////////////////////////////////////
		WindowManager&				operator = ( const WindowManager& rhs )		{return *this;}

		//////////////////////////////////////////////////////////////////////////
		// Interface members.
		bool						Initialize();
		bool						Shutdown();
		bool						BeginDraw();
		bool						Update();
		void						EndDraw();

		//////////////////////////////////////////////////////////////////////////
		// UI interface members.
		bool						LoadFont( const std::string& name );
		bool						LoadFonts( const StringVector_t& names );
		Rocket::Core::ElementDocument*		LoadDocument( const std::string& name );

		//////////////////////////////////////////////////////////////////////////
		//
		static WindowManager*		Instance()									{return mpInstance;}
		int32_t						VideoModeCount() const						{return mFSModes.size();}

		Core::Script&				Script()									{return mScript;}

		typedef std::function< void ( void ) >	PostCall_t;
		void						PushPostCall( PostCall_t );

		void						RunPostCalls();

		Application::Clock&			Clock() const								{return mClock;}

		//////////////////////////////////////////////////////////////////////////
		// Provisional interface.
#ifdef ENABLE_DEVBUILD
		void						ToggleDebugPanel();
		void						ToggleRocketDebugger();
		bool						RocketDebuggerShow() const;
		void						RegisterPanel( TweakUtils::Panel* panel );
#endif

	private:
		//////////////////////////////////////////////////////////////////////////
#ifdef ENABLE_DEVBUILD
		void						_MakeDebugPanel();
#endif
		bool						_CreateMainWindow();
		void						_CloseMainWindow();
		void						_GetVideoModes();
		bool						_InitScript();

		//////////////////////////////////////////////////////////////////////////
		GameWindow*									mpMainWindow;

		DEVBUILD_MEMBER( bool,						mRocketDebugger );
		DEVBUILD( TweakUtils::Panel::EnumType_t		mFSModesEnum );

		std::vector< sf::VideoMode >				mFSModes;

		DEVBUILD( 
			typedef std::vector< TweakUtils::Panel* >	PanelVector_t;
			PanelVector_t							mPanels;
		)

		RocketSystemInterface*						mpSystemInterface;
		FileSystem::RocketFileInterface				mFileInterface;

		Core::Script&								mScript;
		Application::Clock&							mClock;

		std::vector< PostCall_t >					mPostCalls;

		static WindowManager*						mpInstance;
	};
}
